package lock;

import java.util.concurrent.locks.ReentrantLock;

public class LockTest {
    public static void main(String[] args) {
        ReentrantLock lock = new ReentrantLock(false);

        System.out.println("lock is fair: " + lock.isFair());

        Thread thread0 = new Thread() {
            @Override
            public void run() {
                System.out.println("Thread 0 start");

                super.run();

                System.out.println("Thread 0 lock() start");

                lock.lock();

                System.out.println("Thread 0 lock() end");

                System.out.println("Thread 0 unlock() start");

                lock.unlock();

                System.out.println("Thread 0 unlock() end");
            }
        };

        Thread thread1 = new Thread() {
            @Override
            public void run() {
                System.out.println("Thread 1 start");

                super.run();

                System.out.println("Thread 1 lock() start");

                lock.lock();

                System.out.println("Thread 1 lock() end");

                System.out.println("Thread 1 unlock() start");

                lock.unlock();

                System.out.println("Thread 1 unlock() end");
            }
        };

        Thread thread2 = new Thread() {
            @Override
            public void run() {
                System.out.println("Thread 2 start");

                super.run();

                System.out.println("Thread 2 lock() start");

                lock.lock();

                System.out.println("Thread 2 lock() end");

                System.out.println("Thread 2 unlock() start");

                lock.unlock();

                System.out.println("Thread 2 unlock() end");
            }
        };

        Thread thread3 = new Thread() {
            @Override
            public void run() {
                super.run();

                System.out.println("Thread 3 start");

                System.out.println("Thread 3 lock() start");

                lock.lock();

                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                System.out.println("Thread 3 run()");

                System.out.println("Thread 3 unlock() start");

                lock.unlock();

                System.out.println("Thread 3 unlock() end");
            }
        };

        thread3.start();

        try {
            Thread.sleep(1500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        thread0.start();
        thread1.start();
        thread2.start();
    }
}
